package com.xing.lei.happy.utils;


import org.springframework.util.CollectionUtils;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;


@SuppressWarnings("unchecked")
public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
	public static void append(StringBuilder sb, Object... arr) {
		if (sb != null && isNotBlank(arr)) {
			for (Object obj : arr) {
				if (obj != null) {
					sb.append(toString(obj));
				}
			}
		}
	}
	public static String getInstanceName(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof InstanceName) {
			return ((InstanceName) obj).instanceName();
		} else {
			return StringUtils.lowerFirst(getClassName(obj));
		}
	}
	public static String sum(Object... arr) {
		if (ObjectUtils.isBlank(arr)) {
			return null;
		} else {
			StringBuilder sb = new StringBuilder();
			append(sb, arr);
			return sb.toString();
		}
	}


	public static Class<?> getClass(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Class) {
			return (Class<?>) obj;
		} else {
			return obj.getClass();
		}
	}

	public static String getClassName(Object obj) {
		Class<?> clazz = getClass(obj);
		return clazz == null ? null : clazz.getSimpleName();
	}


	public static boolean equalsClass(Object obj1, Object obj2) {
		return getClass(obj1) == getClass(obj2);
	}

	public static boolean notEqualsClass(Object obj1, Object obj2) {
		return !equalsClass(obj1, obj2);
	}

	public static boolean equalsText(Object obj1, Object obj2) {
		if (obj1 == null && obj2 == null) {
			return true;
		}
		if (obj1 == null || obj2 == null) {
			return false;
		}
		return equals(toString(obj1), toString(obj2));
	}

	public static boolean notEqualsText(Object obj1, Object obj2) {
		return !equalsText(obj1, obj2);
	}

	public static Object filter(Object... arr) {
		if (arr != null) {
			for (Object obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static String filter(String... arr) {
		if (arr != null) {
			for (String obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Boolean filter(Boolean... arr) {
		if (arr != null) {
			for (Boolean obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Short filter(Short... arr) {
		if (arr != null) {
			for (Short obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Integer filter(Integer... arr) {
		if (arr != null) {
			for (Integer obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Long filter(Long... arr) {
		if (arr != null) {
			for (Long obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Float filter(Float... arr) {
		if (arr != null) {
			for (Float obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Double filter(Double... arr) {
		if (arr != null) {
			for (Double obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static BigDecimal filter(BigDecimal... arr) {
		if (arr != null) {
			for (BigDecimal obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}

	public static Date filter(Date... arr) {
		if (arr != null) {
			for (Date obj : arr) {
				if (isNotBlank(obj)) {
					return obj;
				}
			}
		}
		return null;
	}
	public static boolean isBlank(Object obj) {
		if (obj == null) {
			return true;
		} else if (obj instanceof CharSequence) {
			return StringUtils.isBlank(obj.toString());
		} else if (ArrayUtils.isArray(obj)) {
			return Array.getLength(obj) == 0;
		} else if (obj instanceof Collection) {
			return CollectionUtils.isEmpty((Collection) obj);
		} else if (obj instanceof Map) {
			return MapUtils.isEmpty((Map) obj);
		} else if (obj instanceof Double) {
			Double d = (Double) obj;
			return d.isInfinite() || d.isNaN();
		} else {
			return false;
		}
	}

	public static boolean isNotBlank(Object obj) {
		return !isBlank(obj);
	}

	public static boolean isAllBlank(Object... arr) {
		if (arr == null) {
			return true;
		}
		for (Object obj : arr) {
			if (isNotBlank(obj)) {
				return false;
			}
		}
		return true;
	}

	public static boolean isAllNotBlank(Object... arr) {
		if (arr == null) {
			return false;
		}
		for (Object obj : arr) {
			if (isBlank(obj)) {
				return false;
			}
		}
		return true;
	}

	public static boolean hasNotBlank(Object... arr) {
		return !isAllBlank(arr);
	}

	public static boolean hasBlank(Object... arr) {
		return !isAllNotBlank(arr);
	}




	public static byte parseByte(Object obj) {
		Byte o = toByte(obj);
		return o == null ? 0 : o;
	}

	public static boolean parseBoolean(Object obj) {
		Boolean o = toBoolean(obj);
		return o == null ? false : o;
	}

	public static short parseShort(Object obj) {
		Short o = toShort(obj);
		return o == null ? 0 : o;
	}

	public static int parseInt(Object obj) {
		Integer o = toInteger(obj);
		return o == null ? 0 : o;
	}

	public static long parseLong(Object obj) {
		Long o = toLong(obj);
		return o == null ? 0 : o;
	}

	public static Float parseFloat(Object obj) {
		Float o = toFloat(obj);
		return o == null ? 0 : o;
	}

	public static double parseDouble(Object obj) {
		Double o = toDouble(obj);
		return o == null ? 0 : o;
	}







	public static String toString(Object obj) {
		return toString(obj, "");
	}

	public static Byte toByte(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Byte) {
			Byte b = (Byte)obj;
			return b;
		} else {
			return StringUtils.toByte(toString(obj));
		}
	}

	public static Boolean toBoolean(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Boolean) {
			Boolean b = (Boolean) obj;
			return b;
		} else {
			return StringUtils.toBoolean(toString(obj));
		}
	}

	public static Short toShort(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Short) {
			Short s = (Short) obj;
			return s;
		} else if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return i.shortValue();
		} else if (obj instanceof Long) {
			Long l = (Long) obj;
			return l.shortValue();
		} else {
			return StringUtils.toShort(toString(obj));
		}
	}

	public static Integer toInteger(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Short) {
			Short s = (Short) obj;
			return s.intValue();
		} else if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return i;
		} else if (obj instanceof Long) {
			Long l = (Long) obj;
			return l.intValue();
		} else {
			return StringUtils.toInteger(toString(obj));
		}
	}

	public static Long toLong(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Short) {
			Short s = (Short) obj;
			return s.longValue();
		} else if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return i.longValue();
		} else if (obj instanceof Long) {
			Long l = (Long) obj;
			return l;
		} else {
			return StringUtils.toLong(toString(obj));
		}
	}

	public static Float toFloat(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Short) {
			Short s = (Short) obj;
			return s.floatValue();
		} else if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return i.floatValue();
		} else if (obj instanceof Long) {
			Long l = (Long) obj;
			return l.floatValue();
		} else if (obj instanceof Float) {
			Float f = (Float) obj;
			return f;
		} else if (obj instanceof Double) {
			Double d = (Double) obj;
			return d.floatValue();
		} else if (obj instanceof BigDecimal) {
			BigDecimal bd = (BigDecimal) obj;
			return bd.floatValue();
		} else {
			return StringUtils.toFloat(toString(obj));
		}
	}

	public static Double toDouble(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Short) {
			Short s = (Short) obj;
			return s.doubleValue();
		} else if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return i.doubleValue();
		} else if (obj instanceof Long) {
			Long l = (Long) obj;
			return l.doubleValue();
		} else if (obj instanceof Float) {
			Float f = (Float) obj;
			return f.doubleValue();
		} else if (obj instanceof Double) {
			Double d = (Double) obj;
			return d;
		} else if (obj instanceof BigDecimal) {
			BigDecimal bd = (BigDecimal) obj;
			return bd.doubleValue();
		} else {
			return StringUtils.toDouble(toString(obj));
		}
	}

	public static BigDecimal toBigDecimal(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Short) {
			Short s = (Short) obj;
			return new BigDecimal(s.toString());
		} else if (obj instanceof Integer) {
			Integer i = (Integer) obj;
			return new BigDecimal(i.toString());
		} else if (obj instanceof Long) {
			Long l = (Long) obj;
			return new BigDecimal(l.toString());
		} else if (obj instanceof Double) {
			Double d = (Double) obj;
			return new BigDecimal(d.toString());
		} else if (obj instanceof BigDecimal) {
			BigDecimal bd = (BigDecimal) obj;
			return bd;
		} else {
			return StringUtils.toBigDecimal(toString(obj));
		}
	}

	public static Date toDate(Object obj) {
		if (obj == null) {
			return null;
		} else if (obj instanceof Date) {
			return (Date) obj;
		} else {
			return StringUtils.toDate(toString(obj));
		}
	}

	public static Map mapObject(Object obj) {
		if (obj instanceof Map) {
			return (Map) obj;
		} else {
			return null;
		}
	}

	public static List listObject(Object obj) {
		if (obj instanceof List) {
			return (List) obj;
		} else {
			return null;
		}
	}

	public static Object toObject(Object obj, Class<?> clazz) {
		if (obj == null || clazz == null) {
			return null;
		} else if (clazz.isAssignableFrom(obj.getClass())) {
			return obj;
		} else if (clazz == String.class) {
			return toString(obj);
		} else if (clazz == Boolean.class || clazz == boolean.class) {
			return toBoolean(obj);
		} else if (clazz == Short.class || clazz == short.class) {
			return toShort(obj);
		} else if (clazz == Integer.class || clazz == int.class) {
			return toInteger(obj);
		} else if (clazz == Long.class || clazz == long.class) {
			return toLong(obj);
		} else if (clazz == Float.class || clazz == float.class) {
			return toFloat(obj);
		} else if (clazz == Double.class || clazz == double.class) {
			return toDouble(obj);
		} else if (clazz == BigDecimal.class) {
			return toBigDecimal(obj);
		} else if (clazz == Date.class) {
			return toDate(obj);
		} else {
			return null;
		}
	}
}